using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;

namespace LS
{
    /// <summary>
    /// 用于记录参数修改状态的类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ModifiableValue<T>
    {
        private T m_Value;
        private bool m_ValueChanged = false;
        private bool m_HasValue = false;
        private Type m_Type = typeof(T);

        /// <summary>
        /// 值
        /// </summary>
        public T Value
        {
            get
            {
                return m_Value;
            }
        }

        /// <summary>
        /// 是否存在值，值类型参数修改后永久为true，引用类型当值非null时返回true。
        /// </summary>
        public bool HasValue
        {
            get
            {
                return m_HasValue;
            }
        }

        /// <summary>
        /// 参数的修改状态，调用SetValue之后会始终返回为true，在调用ClearChangedState()清除其状态后会重置为false。
        /// </summary>
        public bool IsValueChanged
        {
            get
            {
                return m_ValueChanged;
            }
        }

        public ModifiableValue()
        {
            m_ValueChanged = false;
            m_HasValue = false;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="value">初始值</param>
        public ModifiableValue(T value)
        {
            m_ValueChanged = false;
            SetValueWithoutChangedState(value);
        }

        /// <summary>
        /// 设置参数的值，若输入的值与旧值不一致会修改IsValueChanged的状态
        /// </summary>
        /// <param name="value">要设置的值</param>
        public bool SetValue(T value)
        {
            if (m_Type.IsValueType)
            {
                if (m_Value.Equals(value))
                    return false;

                m_HasValue = true;
            }

            if (m_Type.IsClass)
            {
                if (m_Value != null && m_Value.Equals(value))
                    return false;

                if (m_Value == null && value == null)
                    return false;

                m_HasValue = value != null;
            }

            m_Value = value;
            m_ValueChanged = true;
            return true;
        }

        /// <summary>
        /// 获取值，或者返回指定的默认值。
        /// </summary>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public T GetValueOrDefault(T defaultValue)
        {
            if (!m_HasValue)
                return defaultValue;

            return m_Value;
        }

        /// <summary>
        /// 设置值，但不影响其记录的修改状态。
        /// </summary>
        /// <param name="value"></param>
        public void SetValueWithoutChangedState(T value)
        {
            if (m_Type.IsValueType)
            {
                if (m_Value.Equals(value))
                    return;

                m_HasValue = true;
            }

            if (m_Type.IsClass)
            {
                if (m_Value != null && m_Value.Equals(value))
                    return;

                if (m_Value == null && value == null)
                    return;

                m_HasValue = value != null;
            }

            m_Value = value;
        }

        /// <summary>
        /// 清除其记录的修改状态。
        /// </summary>
        public void ClearChangedState()
        {
            m_ValueChanged = false;
        }

        public static implicit operator T(ModifiableValue<T> md)
        {
            return md.Value;
        }

        public static explicit operator ModifiableValue<T>(T value)
        {
            return new ModifiableValue<T>(value);
        }
    }
}
